package com.zhj.common.filter;

import com.alibaba.fastjson.JSON;
import com.zhj.common.entity.ResponseData;
import org.apache.commons.lang3.StringUtils;
import org.springframework.core.annotation.Order;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Component;
import org.springframework.web.filter.OncePerRequestFilter;
import org.springframework.web.util.ContentCachingRequestWrapper;
import org.springframework.web.util.ContentCachingResponseWrapper;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;

/**
 * 默认最后执行
 */
public class ResponseFilter extends OncePerRequestFilter {

    //过滤掉swagger路径
    private static final Set<String> ALLOWED_PATH = Collections.unmodifiableSet(
            new HashSet<>(Arrays.asList(
                    "/swagger-ui.html",
                    "/v2/api-doc",
                    "/swagger-resources",
                    "/webjars")));

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws IOException, ServletException {
        ContentCachingRequestWrapper requestWrapper = new ContentCachingRequestWrapper(request);
        ContentCachingResponseWrapper responseWrapper = new ContentCachingResponseWrapper(response);
        filterChain.doFilter(requestWrapper, responseWrapper);
        wrapResponse(responseWrapper);
        responseWrapper.copyBodyToResponse();
    }

    /**
     * 复写返回值信息
     *
     * @param response
     * @throws IOException
     */
    private void wrapResponse(ContentCachingResponseWrapper response) throws IOException {
        byte[] b = response.getContentAsByteArray();
        // 重置response中的body中的数据，不能使用reset()方法
        if (b.length > 0) {
            response.resetBuffer();
        }
        //请求成功时才需要复写
        if (response.getStatus() == HttpStatus.OK.value()) {
            b = JSON.toJSONBytes(ResponseData.ok(JSON.parse(b)));
        }
        // 通过response的outputStream写入新的数据
        ServletOutputStream outputStream = response.getOutputStream();
        outputStream.write(b);
    }


    /**
     * 跳过swagger路径
     *
     * @param request
     * @return
     */
    @Override
    protected boolean shouldNotFilter(HttpServletRequest request) {
        //过滤掉swagger路径
        String path = request.getRequestURI().substring(request.getContextPath().length()).replaceAll("[/]+$", "");
        return ALLOWED_PATH.stream().anyMatch(path::startsWith) || StringUtils.isBlank(path);
    }


}
